package com.awo.facedetect.activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;

import android.content.pm.ActivityInfo;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;

import com.awo.facedetect.R;
import com.awo.facedetect.analyzer.FaceDetectAnalyzer;
import com.awo.facedetect.util.FileUtil;
import com.awo.facedetect.widget.FaceDrawInfo;
import com.awo.facedetect.widget.FaceDetectInfoView;
import com.awo.facedetect.widget.FaceRectView;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FaceDetectActivity extends AppCompatActivity {

    private static final String TAG = "FaceDetectActivity";

    private ExecutorService cameraExecutor;

    private FaceDetectInfoView fdiv;

    private FaceRectView frv;

    private PreviewView pvv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_face_detect);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        fdiv = findViewById(R.id.fdiv_facedetect_face_rect);
        frv = findViewById(R.id.frv_facedetect_face_rect);
        pvv = findViewById(R.id.pvv_faceDetect_preview);

        // 对视频帧分析启用单独线程
        cameraExecutor = Executors.newSingleThreadExecutor();

        // 打开相机
        startCamera();
    }

    private void startCamera() {
        // 将Camera的生命周期和Activity绑定在一起（设定生命周期所有者），这样就不用手动控制相机的启动和关闭。
        ListenableFuture<ProcessCameraProvider> cameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);

        cameraProviderListenableFuture.addListener(() -> {
            try {
                // 将你的相机和当前生命周期的所有者绑定所需的对象
                ProcessCameraProvider processCameraProvider = cameraProviderListenableFuture.get();

                // 创建一个Preview 实例，并设置该实例的 surface 提供者（provider）。
                PreviewView viewFinder = (PreviewView)findViewById(R.id.pvv_faceDetect_preview);
                Preview preview = new Preview.Builder()
                        .build();
                preview.setSurfaceProvider(viewFinder.getSurfaceProvider());

                // 选择后置摄像头作为默认摄像头
//                CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
                CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;

                // 设置预览帧分析
                ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                        .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)
                        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                        .build();
//                imageAnalysis.setAnalyzer(cameraExecutor, new FaceDetectAnalyzer(this));
                imageAnalysis.setAnalyzer(cameraExecutor, new FaceDetectAnalyzer(this));

                // 重新绑定用例前先解绑
                processCameraProvider.unbindAll();

                // 绑定用例至相机
                processCameraProvider.bindToLifecycle(FaceDetectActivity.this, cameraSelector, preview, imageAnalysis);


            } catch (Exception e) {
                Log.e(TAG, getString(R.string.facedetect_bindUserCaseFailed) + e);
            }
        }, ContextCompat.getMainExecutor(this));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraExecutor.shutdown();
    }

    public int[] getWeightAndHeightOfView() {
        return new int[]{pvv.getWidth(), pvv.getHeight()};
    }

    public PreviewView getPreview() {return pvv;}

    /**
     * 更新人脸框
     * @param faceDrawInfo 人脸框信息
     */
    public void updateFaceRectUIByFDI(FaceDrawInfo faceDrawInfo) {
        runOnUiThread(() -> {
            fdiv.updateFaceDrawInfo(faceDrawInfo);
        });
    }

    public void updateFaceRectUI(FaceDrawInfo faceDrawInfo, Matrix matrix) {
        runOnUiThread(() -> fdiv.updateFaceDrawInfo(faceDrawInfo, matrix));
    }

    public void updateFaceRectUI(Rect faceRect) {
        runOnUiThread(() -> {
            frv.updateFaceDrawInfo(faceRect);
        });
    }
}